package com.zhou.common.mybatis.template.shiro.zhou.exception;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {


    private Logger logger = LoggerFactory.getLogger(getClass());

    @Value("${spring.profiles.active:production}")
    private String             profile;

    @Autowired
    private HttpServletRequest request;


    @ExceptionHandler(Exception.class)
    public Response handleException(Exception e) {
        logger.error(String.format("[%s] : %s, ip : {}", request.getRequestURI(), e.getMessage()),
                getIpAddress(), e);
        logger.error(11111+"");
        return new Response("999",e.getMessage());
    }

    /**
     * 处理自定义异常
     */
    @ExceptionHandler(BizException.class)
    public Response<String> handleMessageException(BizException e) {
        logger.error(String.format("[%s] : %s, ip : {}", request.getRequestURI(), e.getMessage()),
                getIpAddress(), e);
        return new Response("999",e.getMessage());
    }


    @ExceptionHandler(DuplicateKeyException.class)
    public Response<String> handleDuplicateKeyException(DuplicateKeyException e) {
        logger.error(String.format("[%s] : %s, ip : {}", request.getRequestURI(), e.getMessage()),
                getIpAddress(), e);
        return new Response("999",e.getMessage());
    }




    @ExceptionHandler({ MethodArgumentNotValidException.class,
            BindException.class })
    public Response<String> handleArgumentException(Exception e) {
        logger.error(String.format("[%s] : %s, ip : {}", request.getRequestURI(), e.getMessage()),
                getIpAddress(), e);
        BindingResult result;
        if (e instanceof BindException) {
            result = ((BindException) e).getBindingResult();
        } else {
            result = ((MethodArgumentNotValidException) e).getBindingResult();
        }
        FieldError error = result.getFieldError();
        if (Objects.isNull(error)) {
            return new Response("999",e.getMessage());
        }
        String message = error.getDefaultMessage();
        return new Response("999",e.getMessage());
    }

    private String getIpAddress() {
        String ip = request.getHeader("X-Forwarded-For");

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
